﻿using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace AbpCodeGenerater.Core
{
    public class AbpClass
    {
        public string? Name { get; set; }

        public string? FileName { get; set; }

        public string? FullPath { get; set; }

        public AbpProject? AbpProject { get; set; }

        public string? ClassSummary { get; set; }

        public Dictionary<string, string> PropertySummaries { get; set; } = new Dictionary<string, string>();

        public string Context { get; set; } = string.Empty;

        public string? DirectoryPath
        {
            get
            {
                if (AbpProject?.FullPath == null) return null;
                if (FileName == null) return null;

                return FullPath?.Replace(AbpProject.FullPath, "").Replace(FileName, "").TrimStart('\\');
            }
        }

        public string? FullDirectoryPath
        {
            get
            {
                if (FileName == null) return null;

                return FullPath?.Replace(FileName, "").TrimStart('\\');
            }
        }

        public void LoadClass()
        {
            var context = File.ReadAllTextAsync(FullPath ?? string.Empty).Result;
            Context = context;

            PropertySummaries = new Dictionary<string, string>();

            // 创建语法树
            SyntaxTree tree = CSharpSyntaxTree.ParseText(Context);
            var root = tree.GetCompilationUnitRoot();

            var classNode = root.DescendantNodes().OfType<ClassDeclarationSyntax>().FirstOrDefault();
            if (classNode != null)
            {
                ClassSummary = ExtractSummaryFromTrivia(classNode.GetLeadingTrivia());

                var properties = classNode.DescendantNodes().OfType<PropertyDeclarationSyntax>();

                foreach (var propertyDeclare in properties)
                {
                    string summary = ExtractSummaryFromTrivia(propertyDeclare.GetLeadingTrivia());
                    if (!string.IsNullOrEmpty(summary))
                    {
                        PropertySummaries.Add(propertyDeclare.Identifier.Text, summary);
                    }
                }
                if (!PropertySummaries.ContainsKey("IsDeleted")) PropertySummaries.Add("IsDeleted", "是否删除");
                if (!PropertySummaries.ContainsKey("DeleterId")) PropertySummaries.Add("DeleterId", "删除人");
                if (!PropertySummaries.ContainsKey("DeletionTime")) PropertySummaries.Add("DeletionTime", "删除时间");
                if (!PropertySummaries.ContainsKey("LastModifierId")) PropertySummaries.Add("LastModifierId", "最后编辑人");
                if (!PropertySummaries.ContainsKey("LastModificationTime")) PropertySummaries.Add("LastModificationTime", "最后编辑时间");
                if (!PropertySummaries.ContainsKey("CreatorId")) PropertySummaries.Add("CreatorId", "创建人");
                if (!PropertySummaries.ContainsKey("CreationTime")) PropertySummaries.Add("CreationTime", "创建时间");
                if (!PropertySummaries.ContainsKey("ConcurrencyStamp")) PropertySummaries.Add("ConcurrencyStamp", "修改锁");
            }
        }

        static string ExtractSummaryFromTrivia(SyntaxTriviaList triviaList)
        {
            // 查找以"///"或"<!--"开始的Trivia，尝试从中提取summary内容
            var summaryTrivia = triviaList.FirstOrDefault(t => t.ToString().Trim().StartsWith("<summary>", StringComparison.OrdinalIgnoreCase));
            if (summaryTrivia != default(SyntaxTrivia))
            {
                var xml = summaryTrivia.GetStructure() as DocumentationCommentTriviaSyntax;
                if (xml != null)
                {
                    var xmlText = xml.Content.OfType<XmlElementSyntax>().FirstOrDefault();
                    if (xmlText != null)
                    {
                        var text = xmlText.Content.OfType<XmlTextSyntax>().FirstOrDefault()?.TextTokens.FirstOrDefault(x => x.IsKind(SyntaxKind.XmlTextLiteralToken));
                        if (text != null)
                        {
                            return text.Value.ToString().Trim();
                        }
                    }
                }
            }
            return String.Empty;
        }
    }
}
